/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package entidade.controller.JSF;

import entidade.controller.JPA.ProdutoJpaController;
import entidade.controller.JSF.util.PagingInfo;
import entidade.persistencia.Produto;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.faces.FacesException;
import entidade.controller.JSF.util.JsfUtil;
import entidade.controller.JPA.exceptions.NonexistentEntityException;
import entidade.controller.JPA.exceptions.IllegalOrphanException;
import entidade.persistencia.ProdutoCompra;
import entidade.persistencia.ProdutoVenda;
import java.io.File;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Iterator;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.model.SelectItem;
import javax.mail.MessagingException;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import servlets.ProdutoJPAInstance;

/**
 *
 * @author victorinox
 */
public class ProdutoController {

    public ProdutoController() {
        FacesContext facesContext = FacesContext.getCurrentInstance();
        jpaController = (ProdutoJpaController) facesContext.getApplication().getELResolver().getValue(facesContext.getELContext(), null, "produtoJpa");
        ProdutoJPAInstance.getInstance().setJpaController(jpaController);
        pagingInfo = new PagingInfo();
        pagingInfo.setBatchSize(10);
        converter = new ProdutoConverter();
    }
    private Produto produto = null;
    private List<Produto> produtoItems = null;
    private ProdutoJpaController jpaController = null;
    private ProdutoConverter converter = null;
    private PagingInfo pagingInfo = null;

    public PagingInfo getPagingInfo() {
        if (pagingInfo.getItemCount() == -1) {
            pagingInfo.setItemCount(jpaController.getProdutoCount());
        }
        return pagingInfo;
    }

    public SelectItem[] getProdutoItemsAvailableSelectMany() {
        return JsfUtil.getSelectItems(jpaController.findProdutoEntities(), false);
    }

    public SelectItem[] getProdutoItemsAvailableSelectOne() {
        return JsfUtil.getSelectItems(jpaController.findProdutoEntities(), true);
    }

    public Produto getProduto() {
        if (produto == null) {
            produto = (Produto) JsfUtil.getObjectFromRequestParameter("jsfcrud.currentProduto", converter, null);
        }
        if (produto == null) {
            produto = new Produto();
        }
        return produto;
    }

    public String listSetup() {
        reset(true);
        return "produto_list";
    }

    public String listVendaSetup() {
        reset(true);
        return "produto_list_venda";
    }

    public String listCompraSetup() {
        reset(true);
        return "produto_list_compra";
    }

    public String createSetup() {
        reset(false);
        produto = new Produto();
        return "produto_create";
    }

    public String addVenda() {

        FacesContext facesContext = FacesContext.getCurrentInstance();
        VendaController vendaController = (VendaController) facesContext.getApplication().getELResolver().getValue(facesContext.getELContext(), null, "venda");

        List<ProdutoVenda> prodsVenda = vendaController.getVenda().getProdutoVendaCollection();
        if (prodsVenda == null) {
            prodsVenda = new ArrayList<ProdutoVenda>();
        }
        Integer prodId = new Integer(JsfUtil.getRequestParameter("jsfcrud.currentProduto"));

        for (int i = 0; i < prodsVenda.size(); i++) {
            ProdutoVenda produtoVenda = prodsVenda.get(i);
            if (produtoVenda.getProduto().getProdutoId().intValue() == prodId.intValue()) {
                return vendaController.voltarVendaSetup();
            }
        }

        Produto prod = jpaController.findProduto(prodId);
        ProdutoVenda prodVenda = new ProdutoVenda();
        prodVenda.setPrecoUnitario(prod.getPrecoUnitarioProposto());
        prodVenda.setQuantidade(1);
        prodVenda.setProduto(prod);
        prodsVenda.add(prodVenda);

        vendaController.getVenda().setProdutoVendaCollection(prodsVenda);

        vendaController.setIsEditingVenda(true);
        vendaController.calcularParcelas();
        return vendaController.voltarVendaSetup();
    }

    public String addCompra() {

        FacesContext facesContext = FacesContext.getCurrentInstance();
        CompraController compraController = (CompraController) facesContext.getApplication().getELResolver().getValue(facesContext.getELContext(), null, "compra");

        List<ProdutoCompra> prodsCompra = compraController.getCompra().getProdutoCompraCollection();
        if (prodsCompra == null) {
            prodsCompra = new ArrayList<ProdutoCompra>();
        }
        Integer prodId = new Integer(JsfUtil.getRequestParameter("jsfcrud.currentProduto"));

        for (int i = 0; i < prodsCompra.size(); i++) {
            ProdutoCompra produtoCompra = prodsCompra.get(i);
            if (produtoCompra.getProduto().getProdutoId().intValue() == prodId.intValue()) {
                return compraController.voltarCompraSetup();
            }
        }

        Produto prod = jpaController.findProduto(prodId);
        ProdutoCompra prodCompra = new ProdutoCompra();
        prodCompra.setPrecoUnitario(prod.getPrecoUnitarioProposto());
        prodCompra.setQuantidade(1);
        prodCompra.setProduto(prod);
        prodsCompra.add(prodCompra);

        compraController.getCompra().setProdutoCompraCollection(prodsCompra);

        compraController.setIsEditingVenda(true);
        compraController.calcularParcelas();
        return compraController.voltarCompraSetup();
    }

    public String create() {
        try {
            jpaController.create(produto);
            JsfUtil.addSuccessMessage("Produto was successfully created.");
        } catch (Exception e) {
            JsfUtil.ensureAddErrorMessage(e, "A persistence error occurred.");
            return null;
        }
        return listSetup();
    }

    public String detailSetup() {
        return scalarSetup("produto_detail");
    }

    public String editSetup() {
        return scalarSetup("produto_edit");
    }

    private String scalarSetup(String destination) {
        reset(false);
        produto = (Produto) JsfUtil.getObjectFromRequestParameter("jsfcrud.currentProduto", converter, null);
        if (produto == null) {
            String requestProdutoString = JsfUtil.getRequestParameter("jsfcrud.currentProduto");
            JsfUtil.addErrorMessage("The produto with id " + requestProdutoString + " no longer exists.");
            return relatedOrListOutcome();
        }
        return destination;
    }
    public byte[] getImagemProdutoTemp(){
        Produto prod = jpaController.findProduto(1);

        return prod.getImagem();


    }


    public void editImage(HttpServletRequest request) throws IOException, MessagingException, FileUploadException {

        Integer prod_Id = (Integer) request.getSession().getAttribute("produtoEditado");

        Produto prod = jpaController.findProduto(prod_Id);
        if (prod != null) {

            FileItemFactory factory = new DiskFileItemFactory();
            ServletFileUpload upload = new ServletFileUpload(factory);
            List<FileItem> items = upload.parseRequest(request);

            for (Iterator<FileItem> it = items.iterator(); it.hasNext();) {
                FileItem fileItem = it.next();
                prod.setImagem(fileItem.get());
                break;
            }
            try {
                jpaController.edit(prod);
                JsfUtil.addSuccessMessage("Produto was successfully updated.");
            } catch (IllegalOrphanException oe) {
                JsfUtil.addErrorMessages(oe.getMessages());
            } catch (NonexistentEntityException ne) {
                JsfUtil.addErrorMessage(ne.getLocalizedMessage());
            } catch (Exception e) {
                JsfUtil.ensureAddErrorMessage(e, "A persistence error occurred.");
            }
        }
    }

    public String edit() {
        String produtoString = converter.getAsString(FacesContext.getCurrentInstance(), null, produto);
        String currentProdutoString = JsfUtil.getRequestParameter("jsfcrud.currentProduto");
        if (produtoString == null || produtoString.length() == 0 || !produtoString.equals(currentProdutoString)) {
            String outcome = editSetup();
            if ("produto_edit".equals(outcome)) {
                JsfUtil.addErrorMessage("Could not edit produto. Try again.");
            }

            return outcome;
        }

        try {
            jpaController.edit(produto);
            JsfUtil.addSuccessMessage("Produto was successfully updated.");
        } catch (IllegalOrphanException oe) {
            JsfUtil.addErrorMessages(oe.getMessages());
            return null;
        } catch (NonexistentEntityException ne) {
            JsfUtil.addErrorMessage(ne.getLocalizedMessage());
            return listSetup();
        } catch (Exception e) {
            JsfUtil.ensureAddErrorMessage(e, "A persistence error occurred.");
            return null;
        }

        return detailSetup();
    }

    public String destroy() {
        String idAsString = JsfUtil.getRequestParameter("jsfcrud.currentProduto");
        Integer id = new Integer(idAsString);
        try {
            jpaController.destroy(id);
            JsfUtil.addSuccessMessage("Produto was successfully deleted.");
        } catch (IllegalOrphanException oe) {
            JsfUtil.addErrorMessages(oe.getMessages());
            return null;
        } catch (NonexistentEntityException ne) {
            JsfUtil.addErrorMessage(ne.getLocalizedMessage());
            return relatedOrListOutcome();
        } catch (Exception e) {
            JsfUtil.ensureAddErrorMessage(e, "A persistence error occurred.");
            return null;
        }

        return relatedOrListOutcome();
    }

    private String relatedOrListOutcome() {
        String relatedControllerOutcome = relatedControllerOutcome();
        if (relatedControllerOutcome != null) {
            return relatedControllerOutcome;
        }

        return listSetup();
    }

    public List<Produto> getProdutoItems() {
        if (produtoItems == null) {
            getPagingInfo();
            produtoItems =
                    jpaController.findProdutoEntities(pagingInfo.getBatchSize(), pagingInfo.getFirstItem());
        }

        return produtoItems;
    }

    public String next() {
        reset(false);
        getPagingInfo().nextPage();
        return "produto_list";
    }

    public String prev() {
        reset(false);
        getPagingInfo().previousPage();
        return "produto_list";
    }

    public String nextVenda() {
        reset(false);
        getPagingInfo().nextPage();
        return "produto_list_venda";
    }

    public String prevVenda() {
        reset(false);
        getPagingInfo().previousPage();
        return "produto_list_venda";
    }

    public String nextCompra() {
        reset(false);
        getPagingInfo().nextPage();
        return "produto_list_compra";
    }

    public String prevCompra() {
        reset(false);
        getPagingInfo().previousPage();
        return "produto_list_compra";
    }

    private String relatedControllerOutcome() {
        String relatedControllerString = JsfUtil.getRequestParameter("jsfcrud.relatedController");
        String relatedControllerTypeString = JsfUtil.getRequestParameter("jsfcrud.relatedControllerType");
        if (relatedControllerString != null && relatedControllerTypeString != null) {
            FacesContext context = FacesContext.getCurrentInstance();
            Object relatedController = context.getApplication().getELResolver().getValue(context.getELContext(), null, relatedControllerString);
            try {
                Class<?> relatedControllerType = Class.forName(relatedControllerTypeString);
                Method detailSetupMethod = relatedControllerType.getMethod("detailSetup");
                return (String) detailSetupMethod.invoke(relatedController);
            } catch (ClassNotFoundException e) {
                throw new FacesException(e);
            } catch (NoSuchMethodException e) {
                throw new FacesException(e);
            } catch (IllegalAccessException e) {
                throw new FacesException(e);
            } catch (InvocationTargetException e) {
                throw new FacesException(e);
            }

        }
        return null;
    }

    private void reset(boolean resetFirstItem) {
        produto = null;
        produtoItems =
                null;
        pagingInfo.setItemCount(-1);
        if (resetFirstItem) {
            pagingInfo.setFirstItem(0);
        }

    }

    public void validateCreate(FacesContext facesContext, UIComponent component, Object value) {
        Produto newProduto = new Produto();
        String newProdutoString = converter.getAsString(FacesContext.getCurrentInstance(), null, newProduto);
        String produtoString = converter.getAsString(FacesContext.getCurrentInstance(), null, produto);
        if (!newProdutoString.equals(produtoString)) {
            createSetup();
        }

    }

    public Converter getConverter() {
        return converter;
    }

    public int getCrossDockingDataEntregaDia() {
        Calendar cal = Calendar.getInstance();
        cal.setTime(produto.getCrossDockingDataEntrega());
        return cal.get(Calendar.DAY_OF_MONTH);
    }

    public void setCrossDockingDataEntregaDia(int dia) {
        produto.getCrossDockingDataEntrega().setDate(dia);
    }

    public int getCrossDockingDataEntregaMes() {
        Calendar cal = Calendar.getInstance();
        cal.setTime(produto.getCrossDockingDataEntrega());
        return cal.get(Calendar.MONTH) + 1;
    }

    public void setCrossDockingDataEntregaMes(int mes) {
        produto.getCrossDockingDataEntrega().setMonth(mes - 1);
    }

    public int getCrossDockingDataEntregaAno() {
        Calendar cal = Calendar.getInstance();
        cal.setTime(produto.getCrossDockingDataEntrega());
        return cal.get(Calendar.YEAR);
    }

    public void setCrossDockingDataEntregaAno(int ano) {
        produto.getCrossDockingDataEntrega().setYear(ano - 1900);
    }

    public int getVirtualDataEntregaDia() {
        Calendar cal = Calendar.getInstance();
        cal.setTime(produto.getVirtualDataEntrega());
        return cal.get(Calendar.DAY_OF_MONTH);
    }

    public void setVirtualDataEntregaDia(int dia) {
        produto.getVirtualDataEntrega().setDate(dia);
    }

    public int getVirtualDataEntregaMes() {
        Calendar cal = Calendar.getInstance();
        cal.setTime(produto.getVirtualDataEntrega());
        return cal.get(Calendar.MONTH) + 1;
    }

    public void setVirtualDataEntregaMes(int mes) {
        produto.getVirtualDataEntrega().setMonth(mes - 1);
    }

    public int getVirtualDataEntregaAno() {
        Calendar cal = Calendar.getInstance();
        cal.setTime(produto.getVirtualDataEntrega());
        return cal.get(Calendar.YEAR);
    }

    public void setVirtualDataEntregaAno(int ano) {
        produto.getVirtualDataEntrega().setYear(ano - 1900);
    }
}
